/*
 * unicodestringobject.cpp
 *
 *  Created on: Oct 29, 2009
 *  Author: Silviu Caragea
 */

#include "includes/unicodestringobject.h"
#include <sstream>

namespace templatipus
{

	template<typename T> void TUnicodeStringObject::internalNumberToString(std::wstring & buffer, const T value)
	{
		std::wostringstream ss;
		ss << value;
		buffer = ss.str();
	}

	//constructors

	TUnicodeStringObject::TUnicodeStringObject():TStringObject()
	{

	}

	TUnicodeStringObject::TUnicodeStringObject(const TemplateObject &other):TStringObject(other)
	{
		if (this != &other)
			this->internalBuffer = (std::wstring) other;
	}

	TUnicodeStringObject::TUnicodeStringObject(const tbool &rhs):TStringObject(rhs)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, rhs);
	}

	TUnicodeStringObject::TUnicodeStringObject(const int8 &rhs):TStringObject(rhs)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, rhs);
	}

	TUnicodeStringObject::TUnicodeStringObject(const int16 &rhs):TStringObject(rhs)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, rhs);
	}

	TUnicodeStringObject::TUnicodeStringObject(const int32 &rhs):TStringObject(rhs)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, rhs);
	}

	TUnicodeStringObject::TUnicodeStringObject(const int64 &rhs):TStringObject(rhs)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, rhs);
	}

	TUnicodeStringObject::TUnicodeStringObject(const float32 &rhs):TStringObject(rhs)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, rhs);
	}

	TUnicodeStringObject::TUnicodeStringObject(const float64 &rhs):TStringObject(rhs)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, rhs);
	}

	TUnicodeStringObject::TUnicodeStringObject(const std::string& rhs):TStringObject(rhs)
	{
		this->internalBuffer = internalBuffer.assign(rhs.begin(), rhs.end());
	}

	TUnicodeStringObject::TUnicodeStringObject(const std::wstring& rhs):TStringObject(rhs)
	{
		this->internalBuffer = rhs;
	}

	TUnicodeStringObject::TUnicodeStringObject(const unicodePtr &rhs):TStringObject(rhs)
	{
		this->internalBuffer = rhs;
	}

	TUnicodeStringObject::TUnicodeStringObject(const utf8Ptr &rhs):TStringObject(rhs)
	{
		std::string ws(rhs);
		this->internalBuffer = internalBuffer.assign(ws.begin(), ws.end());
	}

	TUnicodeStringObject::~TUnicodeStringObject()
	{

	}

	//base methods

	TObjectType TUnicodeStringObject::getType() const
	{
		return STRING_UNICODE_TYPE;
	}

	//operations
	TUnicodeStringObject TUnicodeStringObject::operator +(const TemplateObject &other)
	{
		TUnicodeStringObject obj = internalBuffer;
		obj += other;

		return obj;
	}

	const TemplateObject& TUnicodeStringObject::operator +=(
			const TemplateObject &other)
	{
		internalBuffer.append(((std::wstring) other).c_str());
		return *this;
	}

	//assignment

	TemplateObject& TUnicodeStringObject::operator=(const TemplateObject &other)
	{
		if (this != &other)
			this->internalBuffer = (std::wstring)other;

		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const int8 &other)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, other);
		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const int16 &other)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, other);
		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const int32 &other)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, other);
		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const int64 &other)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, other);
		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const float32 &other)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, other);
		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const float64 &other)
	{
		TUnicodeStringObject::internalNumberToString(internalBuffer, other);
		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const std::string& other)
	{
		this->internalBuffer.assign(other.begin(), other.end());
		return *this;
	}

	TemplateObject& TUnicodeStringObject::operator=(const std::wstring& other)
	{
		internalBuffer = other;
		return *this;
	}

	//conversions to numbers
	tbool TUnicodeStringObject::toBool() const
	{
		int32 temp;
		swscanf(internalBuffer.c_str(), L"%ld", &temp);
		return (tbool)temp;
	}

	int8 TUnicodeStringObject::toInt8() const
	{
		int32 temp;
		swscanf(internalBuffer.c_str(), L"%ld", &temp);
		return (int8)temp;
	}

	uint8 TUnicodeStringObject::toUint8() const
	{
		int32 temp;
		swscanf(internalBuffer.c_str(), L"%ld", &temp);
		return (uint8)temp;
	}

	int16 TUnicodeStringObject::toInt16() const
	{
		int32 temp;
		swscanf(internalBuffer.c_str(), L"%ld", &temp);
		return (int16)temp;
	}

	uint16 TUnicodeStringObject::toUint16() const
	{
		int32 temp;
		swscanf(internalBuffer.c_str(), L"%ld", &temp);
		return (uint16)temp;
	}

	int32 TUnicodeStringObject::toInt32() const
	{
		int32 temp;
		swscanf(internalBuffer.c_str(), L"%ld", &temp);
		return temp;
	}

	uint32 TUnicodeStringObject::toUint32() const
	{
		uint32 temp;
		swscanf(internalBuffer.c_str(), L"%lu", &temp);
		return temp;
	}

	int64 TUnicodeStringObject::toInt64() const
	{
		int64 temp;
		swscanf(internalBuffer.c_str(), WPRINTF_INT64_MODIFIER, &temp);
		return temp;
	}

	uint64 TUnicodeStringObject::toUint64() const
	{
		uint64 temp;
		swscanf(internalBuffer.c_str(), WPRINTF_INT64_MODIFIER, &temp);
		return temp;
	}

	float32 TUnicodeStringObject::toFloat32() const
	{
		float32 temp;
		swscanf(internalBuffer.c_str(), L"%f", &temp);
		return temp;
	}

	float64 TUnicodeStringObject::toFloat64() const
	{
		float64 temp;
		swscanf(internalBuffer.c_str(), L"%lf", &temp);
		return temp;
	}

	std::string TUnicodeStringObject::toString() const
	{
		std::string ws;
		ws.assign(internalBuffer.begin(),internalBuffer.end());
		return ws;
	}

	std::wstring TUnicodeStringObject::toWString() const
	{
		return this->internalBuffer;
	}

	//methods comparison

	tbool TUnicodeStringObject::equals(const TemplateObject &other) const
	{
		const std::wstring & toStr = other;
		return (internalBuffer.compare(toStr.c_str()) == 0);
	}

	tbool TUnicodeStringObject::notEquals(const TemplateObject &other)const
	{
		const std::wstring & toStr = other;
	    return (internalBuffer.compare(toStr.c_str()) != 0);
	}

	tbool TUnicodeStringObject::greater(const TemplateObject &other) const
	{
		const std::wstring & toStr = other;
	    return (internalBuffer.compare(toStr.c_str()) > 0);
	}

	tbool TUnicodeStringObject::less(const TemplateObject &other) const
	{
		const std::wstring & toStr = other;
	    return (internalBuffer.compare(toStr.c_str()) < 0);
	}

	tbool TUnicodeStringObject::lessOrEquals(const TemplateObject &other) const
	{
		const std::wstring & toStr = other;
	    return (internalBuffer.compare(toStr.c_str()) <= 0);
	}

	tbool TUnicodeStringObject::greaterOrEquals(const TemplateObject &other) const
	{
		const std::wstring & toStr = other;
	    return (internalBuffer.compare(toStr.c_str()) >= 0);
	}

	//stuff

	unicodec TUnicodeStringObject::operator [](const uint32 index)
	{
		return (unicodec)this->characterAtIndex(index);
	}

	uint32 TUnicodeStringObject::getLength()
	{
		return (uint32)internalBuffer.size();

	}

	unicodec TUnicodeStringObject::characterAtIndex(uint32 index)
	{
		if (index < internalBuffer.size())
			return internalBuffer.at(index);

		return NULL;
	}

	//append operations

	void TUnicodeStringObject::appendString(TStringObject &object)
	{
		internalBuffer.append(((std::wstring)object).c_str());
	}

	void TUnicodeStringObject::appendUint8(uint8 nr)
	{
		std::wstring buffer;
		TUnicodeStringObject::internalNumberToString(buffer, nr);
		internalBuffer.append(buffer);
	}

	void TUnicodeStringObject::appendInt16(int16 nr)
	{
		std::wstring buffer;
		TUnicodeStringObject::internalNumberToString(buffer, nr);
		internalBuffer.append(buffer);
	}

	void TUnicodeStringObject::appendUint16(uint16 nr)
	{
		std::wstring buffer;
		TUnicodeStringObject::internalNumberToString(buffer,  nr);
		internalBuffer.append(buffer);
	}

	void TUnicodeStringObject::appendInt32(int32 nr)
	{
		std::wstring buffer;
		TUnicodeStringObject::internalNumberToString(buffer, nr);
		internalBuffer.append(buffer);
	}

	void TUnicodeStringObject::appendUint32(uint32 nr)
	{
		std::wstring buffer;
		TUnicodeStringObject::internalNumberToString(buffer,  nr);
		internalBuffer.append(buffer);
	}

	void TUnicodeStringObject::appendInt64(int64 nr)
	{
		std::wstring buffer;
		TUnicodeStringObject::internalNumberToString(buffer,  nr);
		internalBuffer.append(buffer);
	}

	void TUnicodeStringObject::appendUint64(uint64 nr)
	{
		std::wstring buffer;
		TUnicodeStringObject::internalNumberToString(buffer, nr);
		internalBuffer.append(buffer);
	}

	void TUnicodeStringObject::appendUtf8Ptr(unicodePtr ptr)
	{
		internalBuffer.append(ptr);
	}

	void TUnicodeStringObject::appendString(std::wstring &str)
	{
		internalBuffer.append(str);
	}

}
